package cn.iocoder.yudao.module.system.service.ai;

import cn.iocoder.yudao.module.system.dal.dataobject.ai.AiAdmissionCutoffScoreDO;
import cn.iocoder.yudao.module.system.dal.dataobject.college.CollegeDO;
import cn.iocoder.yudao.module.system.dal.dataobject.gugu.MajorAdmissionDO;
import cn.iocoder.yudao.module.system.dal.mysql.ai.AiAdmissionCutoffScoreMapper;
import cn.iocoder.yudao.module.system.dal.mysql.college.CollegeMapper;
import cn.iocoder.yudao.module.system.dal.mysql.gugu.MajorAdmissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * AI志愿推荐缓存服务实现
 * 
 * @author 芋道源码
 */
@Service
@Slf4j
public class AiVolunteerRecommendCacheServiceImpl implements AiVolunteerRecommendCacheService {

    @Resource
    private CollegeMapper collegeMapper;
    
    @Resource
    private MajorAdmissionMapper majorAdmissionMapper;
    
    @Resource
    private AiAdmissionCutoffScoreMapper aiAdmissionCutoffScoreMapper;

    /**
     * 缓存学校基础信息（24小时过期）
     * value值定义了Redis key前缀：ai:college:info
     * TTL在application.yml中配置：spring.cache.redis.time-to-live
     */
    @Override
    @Cacheable(
        cacheManager = "aiVolunteerCacheManager",
        value = "ai:college:info", 
        key = "#schoolUuids.hashCode()", 
        unless = "#result == null || #result.isEmpty()"
    )
    public Map<String, CollegeDO> getCollegeInfo(List<String> schoolUuids) {
        if (schoolUuids == null || schoolUuids.isEmpty()) {
            return Collections.emptyMap();
        }
        
        log.info("[Redis Cache Miss] 查询学校信息 {} 个", schoolUuids.size());
        
        // 分批查询避免IN条件过多
        int batchSize = 300;
        List<CollegeDO> allColleges = schoolUuids.stream()
                .collect(Collectors.groupingBy(uuid -> schoolUuids.indexOf(uuid) / batchSize))
                .values().stream()
                .flatMap(batch -> collegeMapper.selectList("school_uuid", batch).stream())
                .collect(Collectors.toList());
        
        return allColleges.stream()
                .collect(Collectors.toMap(CollegeDO::getSchoolUuid, c -> c, (c1, c2) -> c1));
    }

    /**
     * 缓存历史录取数据（永久缓存，历史数据不会变化）
     * TTL设置为7天，实际可以更长
     */
    @Override
    @Cacheable(
        cacheManager = "aiVolunteerCacheManager",
        value = "ai:history:admissions", 
        key = "#schoolUuids.hashCode() + ':' + #province + ':' + #year + ':' + #classify + ':' + #batch",
        unless = "#result == null || #result.isEmpty()"
    )
    public Map<String, List<MajorAdmissionDO>> getHistoryAdmissions(
            List<String> schoolUuids,
            String province,
            Integer year,
            String classify,
            String batch) {
        
        if (schoolUuids == null || schoolUuids.isEmpty()) {
            return Collections.emptyMap();
        }
        
        log.info("[Redis Cache Miss] 查询历史录取数据 {} 个学校，年份={}，类型={}", 
                schoolUuids.size(), year, classify);
        
        // 分批查询
        int batchSize = 300;
        List<MajorAdmissionDO> allAdmissions = schoolUuids.stream()
                .collect(Collectors.groupingBy(uuid -> schoolUuids.indexOf(uuid) / batchSize))
                .values().stream()
                .flatMap(batchUuids -> {
                    return majorAdmissionMapper.selectListBySchoolUuidsAndProvince(
                            batchUuids,
                            province,
                            List.of(year),
                            classify,
                            batch
                    ).stream();
                })
                .collect(Collectors.toList());
        
        // 按学校UUID分组
        return allAdmissions.stream()
                .collect(Collectors.groupingBy(MajorAdmissionDO::getSchoolUuid));
    }

    /**
     * 缓存AI录取分数线数据（6小时过期，当年数据可能更新）
     */
    @Override
    @Cacheable(
        cacheManager = "aiVolunteerCacheManager",
        value = "ai:cutoff:scores",
        key = "#schoolNames.hashCode() + ':' + #year + ':' + #classify + ':' + (#province != null ? #province : 'null') + ':' + (#batch != null ? #batch : 'null')",
        unless = "#result == null || #result.isEmpty()"
    )
    public List<AiAdmissionCutoffScoreDO> getCutoffScores(
            List<String> schoolNames,
            Integer year,
            String classify, String province, String batch) {
        
        if (schoolNames == null || schoolNames.isEmpty()) {
            return Collections.emptyList();
        }
        
        log.info("[Redis Cache Miss] 查询AI录取分数线 {} 个学校，年份={}，类型={}，省份={}，批次={}", 
                schoolNames.size(), year, classify, province, batch);
        
        return aiAdmissionCutoffScoreMapper.selectBatchByYearSchoolsType(year, schoolNames, classify,province,batch);
    }
    
    @Override
    public List<AiAdmissionCutoffScoreDO> getCutoffScoresByUuids(
            List<String> schoolUuids,
            Integer year,
            String classify, String province, String batch) {
        
        if (schoolUuids == null || schoolUuids.isEmpty()) {
            return Collections.emptyList();
        }
        
        log.info("【优化】查询AI录取分数线（UUID）{} 个学校，年份={}，类型={}，省份={}，批次={}", 
                schoolUuids.size(), year, classify, province, batch);
        
        return aiAdmissionCutoffScoreMapper.selectBatchByYearSchoolUuidsType(year, schoolUuids, classify, province, batch);
    }
}


